package channel_define

import (
	storage_define "go-iot-gateway/internal/storage/define"
	"sync"
)

// ConnectChannel 连接通道
type ConnectChannel interface {
	//Open 打开通道连接, 创建各种资源如通道、线程池等
	//该操作应该只执行一次
	Open()
	//Close 关闭通道连接,释放资源
	//应该在系统在关闭时会主动调用
	Close()
	//Info 获取当前的通道信息
	Info() ChannelInfo
	//todo 获取连接对象
	//todo 监听
}

// WritableChannel 可写通道
type WritableChannel interface {
	//WriteBytes  是大端序
	WriteBytes(tagId string, bytes []byte) error
}

// ReadableChannel 可读通道
type ReadableChannel interface {
	ReadVal(key string) storage_define.ValObject
}

// ConnectStatusType 连接状态： 0 创建 ， 1 连接中 ，2 连接上 ，3 断开
type ConnectStatusType int

const (
	CONNECT_STATUS_CREATE     ConnectStatusType = iota //连接创建
	CONNECT_STATUS_CONNECTING                          //连接中
	CONNECT_STATUS_CONNECTED                           //连接正常
	CONNECT_STATUS_CLOSED                              //程序调用主动关闭
	CONNECT_STATUS_ERROR                               //连接出现问题
)

// ConnectParams 连接参数
type ConnectParams struct {
	IpAddr   string `json:"ip_addr"` //tcp
	Port     uint16 `json:"port"`
	Role     int    `json:"role"` //连接方式 0 主动 1 被动
	Timeout  int    `json:"timeout"`
	Baud     uint32 `json:"baud"` //serial
	CheckBit byte   `json:"check_bit"`
	ComName  string `json:"com_name"`
	DataBit  uint8  `json:"data_bit"`
	StopBit  uint8  `json:"stop_bit"`
}

var lock sync.Mutex

// ChannelInfo 通道信息
type ChannelInfo struct {
	ChlId         string
	Name          string
	Addr          int64
	Desc          string
	Protocol      string
	ChannelType   int           //0 采集 |  1 转发
	ProtocolType  int           // 0 tcp 口 |  1 串口
	WaitTime      int           //每帧间隔
	Frequency     int           //交互频率
	ConnectParams ConnectParams //连接参数
	Status        ConnectStatusType
	StatusDesc    string
}

func (info *ChannelInfo) SetStatus(val ConnectStatusType, connectStatusDesc string) {
	lock.Lock()
	defer lock.Unlock()
	info.Status = val
	info.StatusDesc = connectStatusDesc
}

// IsTCPProtocol 是否是 tcp 协议
func (info *ChannelInfo) IsTCPProtocol() bool {
	return info.ProtocolType == 0
}
